package com.bang.study.day02.map;

/**
 * @Auther: Bang
 * @Date: 2019/9/13 22:47
 * @Description: 以链表为基础实现map
 */
public class LinkedListMap<K,V> implements Map<K, V> {

    /**
     * 虚拟头结点
     */
    private Node dummyNode;

    private int size;

    private class Node{
        public K key;

        public V value;

        private Node next;

        public Node() {
            this(null, null, null);
        }

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
            this.next = null;
        }

        public Node(K key, V value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
        @Override
        public String toString(){
            return key.toString() + " : " + value.toString();
        }
    }

    public LinkedListMap() {
        this.dummyNode = new Node();
        this.size = 0;
    }

    @Override
    public void add(K key, V value) {
        Node node = getNode(key);
        if (node==null) {
            dummyNode.next = new Node(key, value, dummyNode.next);
            size++;
        }else{
            node.value=value;
        }
    }

    @Override
    public void set(K key, V newValue) {
        Node node = getNode(key);
        if (node==null) {
            throw new IllegalArgumentException(key + " doesn't exist!");
        }else{
            node.value = newValue;
        }
    }

    @Override
    public V remove(K key) {
        Node prev = dummyNode.next;
        while (prev.next!=null){
            K currKey = prev.next.key;
            if (key==null) {
                if (currKey==null){
                    break;
                }else{
                    prev = prev.next;
                }
            }else{
                if (key.equals(currKey)) {
                    break;
                }
                prev = prev.next;
            }
        }
        if (prev.next==null) {
            return null;
        }else {
            Node delNode = prev.next;
            prev.next = delNode.next;
            delNode = null;
            size--;
            return delNode.value;
        }
    }

    @Override
    public V get(K key) {
        Node node = getNode(key);
        return node==null?null:node.value;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean contains(K key) {
        return getNode(key) != null;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    private Node getNode(K key) {
        Node curr = dummyNode;
        while (curr!=null){
            K currKey = curr.key;
            if (key.equals(currKey)) {
                return curr;
            }
            curr = curr.next;
        }
        return null;
    }


}
